﻿using System;
using System.Collections.Generic;
using Epitech.Krisk.Xna.ScreenManagerLib.ScreenManager;
using Epitech.Krisk.Xna.ScreenManagerLib.Widget;
using Epitech.Krisk.Xna.UI.Game.InGame.Gameplay;
using Epitech.Krisk.Xna.UI.Game.Utils;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Epitech.Krisk.Xna.UI.Game.InGame
{
    enum AnimState
    {
        State1,
        State2,
        State3
    }

    public class MenuGame : AGameObject
    {

        #region Fields

        Texture2D _menu;
        private List<ClickableCard> _cardsList;
        List<MenuEntry> _buttonList;
        private SpriteFont _font;
        private readonly GamePlay _gamePlay;
        double _y;
        private readonly GameScreen _screen;
        private MenuEntry _player;
        private MenuEntry _buttonStep;
        private DateTime _lastclick = DateTime.Now;

        private AnimState _stepAnimStep;
        private String _step = "Renfort";
        private Vector2 _posStep;
        private Vector2 _vectorDir;
        private TimeSpan _newstep;
        private TurnState _lastStep = TurnState.None;
        private float _scaleStep = 1f;

        private Texture2D _combats;
        private Texture2D _renfort;
        private Texture2D _move;

        #endregion

        #region Constructor
        
        public MenuGame(GameScreen parent, GamePlay gamePlay)
        {
            _screen = parent;
            _gamePlay = gamePlay;
            _cardsList = new List<ClickableCard>();
        }

        #endregion

        #region Boucle

        public override void Draw(GameTime gameTime)
        {
            Rectangle winSize = new Rectangle(0, (int)_y, ViewPort.Width, ViewPort.Height - (int)_y);

            SpriteBatch.Begin();

            #region Menu

            Rectangle minimap = new Rectangle(1341, (int)_y + 8, 300, 196);

            SpriteBatch.Draw(_menu, winSize, Color.WhiteSmoke);

            #endregion

            #region Buttons

            foreach (MenuEntry item in _buttonList)
            {
                item.Draw(_screen, false, gameTime);
            }

            #endregion


            Vector2 pos = new Vector2(ViewPort.Width - 510, ViewPort.Height - 150);
            SpriteBatch.DrawString(_font, String.Format("{0} : {1}", "Renforts", _gamePlay.GameTurn.Player.ReinforcementArmy), pos, Color.Black, 0f, Vector2.Zero, 0.6f, SpriteEffects.None, 0f);
            pos += new Vector2(0, 40);
            SpriteBatch.DrawString(_font, String.Format("{0} : {1}", "Territoires", _gamePlay.GameTurn.Player.OwnTerritory.Count), pos, Color.Black, 0f, Vector2.Zero, 0.6f, SpriteEffects.None, 0f);

            SpriteBatch.Draw(_textureStep, _rectStep, null, Color.White);
            if (_gamePlay.GameTurn.Player.QuestCard != null)
            {
                if (_gamePlay.GameTurn.Player.QuestCard.Texture == null)
                    _gamePlay.GameTurn.Player.QuestCard.LoadContent(Content);
                if (_gamePlay.GameTurn.Player.QuestCard.Texture != null)
                {
                    if (!_normalSize)
                        SpriteBatch.Draw(_gamePlay.GameTurn.Player.QuestCard.Texture, _recObj, Color.White);
                    else
                        SpriteBatch.Draw(_gamePlay.GameTurn.Player.QuestCard.Texture, new Vector2(1225, 386),
                                         Color.White);
                }
            }

            SpriteBatch.End();

            #region Cards

            if (_cardsList != null)
            {
                foreach (ClickableCard clickableCard in _cardsList)
                {
                    clickableCard.Draw(gameTime);
                } 
            }

            #endregion

        }

        public override void HandleInput(InputState input)
        {
            #region Button HandleInput

            foreach (MenuEntry item in _buttonList)
            {
                item.HandleInput(_screen, input);
            }

            #endregion

            #region Cards

            if (_cardsList != null)
            {
                foreach (ClickableCard clickableCard in _cardsList)
                {
                    clickableCard.HandleInput(input);
                }
            }

            #endregion

            #region Objectif

            _normalSize = _recObj.Contains((int)input.MousePosition().X, (int)input.MousePosition().Y);

            #endregion
        }

        public override void LoadContent()
        {
            Texture2D bm = Content.Load<Texture2D>("Game/ButtonMenuGame");
            _menu = Content.Load<Texture2D>("Game/MenuGame");
            _font = Content.Load<SpriteFont>("Font/defaultfont");
            _renfort = Content.Load<Texture2D>("Game/MenuGame/Renforts");
            _combats = Content.Load<Texture2D>("Game/MenuGame/Combats");
            _move = Content.Load<Texture2D>("Game/MenuGame/Mouvements");
            _textureStep = _renfort;
            _y = ViewPort.Height * (1 - 0.22);

            _buttonList = new List<MenuEntry>();

            MenuEntry echange = new MenuEntry("Game/ButtonMenuGame", "Echanger")
            {
                Position =
                    new Vector2(ViewPort.Width / 2 - bm.Width - 10, (float)ViewPort.Height - 70)
            };
            MenuEntry suppr = new MenuEntry("Game/ButtonMenuGame", "Supprimer")
            {
                Position =
                    new Vector2(ViewPort.Width / 2 + 10, (float)ViewPort.Height - 70)
            };
            suppr.Selected += OnSupprClick;
            echange.Selected += OnEchangeClick;
            _buttonList.Add(echange);
            _buttonList.Add(suppr);
            _buttonStep = new MenuEntry("Game/ButtonMenuGame", "Suivant") { Position = new Vector2(50, (float)ViewPort.Height - 70) };
            _buttonStep.Selected += NextStep;
            _buttonList.Add(_buttonStep);
            _player = new MenuEntry("Game/ButtonMenuGame", "Player") { Position = new Vector2(50, (float)ViewPort.Height - 180) };
            _buttonList.Add(_player);

            _recObj = new Rectangle(ViewPort.Width - 150, ViewPort.Height - 210, 135, 200);

            foreach (MenuEntry item in _buttonList)
            {
                item.FontSize = 1f;
                item.SelectedColor = new Color(119, 121, 81);
                item.DefaultColor = new Color(208, 44, 6);
                item.IsPulse = false;
                item.LoadContent(_screen);
            }
        }

        public override void UnloadContent()
        {
        }

        private Player _last = null;
        private Texture2D _textureStep;
        private Rectangle _rectStep;
        private const float TextureScale = 0.4f;
        private Rectangle _recObj;
        private bool _normalSize;


        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            #region Turn Update

            if (_lastStep != _gamePlay.GameTurn.State)
            {
                _scaleStep = 1f;
                switch (_gamePlay.GameTurn.State)
                {
                    case TurnState.Begin:
                        _textureStep = _renfort;
                        break;
                    case TurnState.Fight:
                        _textureStep = _combats;
                        break;
                    case TurnState.Move:
                        _textureStep = _move;
                        break;
                }
                _lastStep = _gamePlay.GameTurn.State;
                _rectStep = new Rectangle((int) (ViewPort.Width / 2 - _textureStep.Width * TextureScale * _scaleStep / 2), (int) (ViewPort.Height / 2 - _textureStep.Height * _scaleStep * TextureScale / 2),
                    (int) (_textureStep.Width * _scaleStep * TextureScale), (int) (_textureStep.Height * _scaleStep * TextureScale));

                _newstep = gameTime.TotalGameTime;
                _stepAnimStep = AnimState.State1;
            }

            if (_stepAnimStep == AnimState.State1)
            {
                if (gameTime.TotalGameTime - _newstep < TimeSpan.FromSeconds(0.5))
                {
                    _scaleStep += 2*(float) gameTime.ElapsedGameTime.TotalSeconds;
                    _rectStep = new Rectangle((int)(ViewPort.Width / 2 - _textureStep.Width * TextureScale * _scaleStep / 2), (int)(ViewPort.Height / 2 - _textureStep.Height * _scaleStep * TextureScale / 2),
                    (int)(_textureStep.Width * _scaleStep * TextureScale), (int)(_textureStep.Height * _scaleStep * TextureScale));
                }
                else
                {
                    _posStep = new Vector2(_rectStep.X, _rectStep.Y);
                    _vectorDir = new Vector2(ViewPort.Width - 500, ViewPort.Height - 190);
                    _vectorDir -= _posStep;
                    _vectorDir /= 0.5f;
                    _stepAnimStep = AnimState.State2;
                    _newstep = gameTime.TotalGameTime;
                }
            }
            else if (_stepAnimStep == AnimState.State2)
            {
                if (gameTime.TotalGameTime - _newstep > TimeSpan.FromSeconds(0.5))
                {
                    _newstep = gameTime.TotalGameTime;
                    _stepAnimStep = AnimState.State3;
                }  
            }
            else
            {
                if (gameTime.TotalGameTime - _newstep < TimeSpan.FromSeconds(0.5))
                {
                    _posStep += _vectorDir*(float) gameTime.ElapsedGameTime.TotalSeconds;
                    _rectStep = new Rectangle((int) _posStep.X, (int) _posStep.Y,
                    (int)(_textureStep.Width * _scaleStep * TextureScale), (int)(_textureStep.Height * _scaleStep * TextureScale));
                    _scaleStep -= 2 * (float)gameTime.ElapsedGameTime.TotalSeconds;
                }
                else
                {
                    _scaleStep = 1f;
                }
            }

            #endregion

            #region Player Update

            _player.Textover = _gamePlay.GameTurn.Player.Name;
            _player.DefaultColor = _gamePlay.GameTurn.Player.Color;

            #endregion

            #region ButtonUpdate

            foreach (MenuEntry item in _buttonList)
            {
                item.Update(_screen, false, gameTime);
            }

            #endregion

            #region Cards Update

            if (_last != _gamePlay.GameTurn.Player)
            {
                _cardsList.Clear();
            }

            int x = 548;

            x += 120 * _cardsList.Count;
            foreach (var territoryCard in _gamePlay.GameTurn.Player.Cards)
            {
                bool ok = true;

                for (int i = 0; i < _cardsList.Count; i++)
                {
                    if (_cardsList[i].Card == territoryCard.Texture)
                        ok = false;
                }
                if (ok)
                {
                    ClickableCard card = new ClickableCard
                                             {
                                                 Card = territoryCard.Texture,
                                                 Resize = new Rectangle(x, (int) _y + 2, 103, 152),
                                                 SelectedColor = new Color(119, 121, 81),
                                                 SpriteBatch = SpriteBatch,
                                                 TerritoryCard = territoryCard
                                             };
                    _cardsList.Add(card);
                    x += 120;
                }
            }

            _last = _gamePlay.GameTurn.Player;

            #endregion
        }

        #endregion

        #region Methods

        private void OnSupprClick(object sender, PlayerIndexEventArgs e)
        {
            List<ClickableCard> toremove = new List<ClickableCard>();

            Sound.GetInstance().setMusic("Music/ButtonSound");
            foreach (var clickableCard in _cardsList)
            {
                if (clickableCard.IsSelected)
                    toremove.Add(clickableCard);
            }

            RemoveCards(toremove);
        }

        private void RemoveCards(List<ClickableCard> cards)
        {
            foreach (var clickableCard in cards)
            {
                _cardsList.Remove(clickableCard);
                _gamePlay.RemoveCard(clickableCard);
            }
            int x = 548;

            foreach (var clickableCard in _cardsList)
            {
                clickableCard.Resize = new Rectangle(x, (int)_y + 2, 103, 152);
                x += 120;
            }
        }

        private void OnEchangeClick(object sender, PlayerIndexEventArgs playerIndexEventArgs)
        {
            Sound.GetInstance().setMusic("Music/ButtonSound");
            List<ClickableCard> selected = new List<ClickableCard>();

            foreach (var clickableCard in _cardsList)
            {
                if (clickableCard.IsSelected)
                    selected.Add(clickableCard);
            }

            if (selected.Count > 0)
            {
                if (_gamePlay.EchangeCard(selected))
                    RemoveCards(selected);
            }
        }

        private void NextStep(object sender, PlayerIndexEventArgs playerIndexEventArgs)
        {
            if (DateTime.Now - _lastclick > TimeSpan.FromSeconds(1))
            {
                Sound.GetInstance().setMusic("Music/ButtonSound");
                _gamePlay.NextTurn();
                _lastclick = DateTime.Now;
            }
        }

        #endregion
    }
}
